﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace JEngine.Framework
{
    /// <summary>
    /// 面板管理器
    /// </summary>
    public class PanelManager
    {
        /// <summary>
        /// 排序间隔
        /// </summary>
        private const int ORDER_SPACE = 100;

        /// <summary>
        /// canvas
        /// </summary>
        private Canvas canvas;

        /// <summary>
        /// Canvas
        /// </summary>
        public Canvas Canvas
        {
            get { return canvas; }
        }

        /// <summary>
        /// CanvasScaler
        /// </summary>
        private CanvasScaler canvasScaler;

        /// <summary>
        /// GraphicRaycaster
        /// </summary>
        private GraphicRaycaster graphicRaycaster;

        /// <summary>
        /// 默认的轴心
        /// </summary>
        private Vector2 DefaultPivot = new Vector2(0.5f, 0.5f);

        /// <summary>
        /// mrgRoot
        /// </summary>
        private Transform mrgRoot;

        /// <summary>
        /// UI挂载点
        /// </summary>
        private Transform uiRoot;

        /// <summary>
        /// 固定层级UI挂载点
        /// </summary>
        private Transform MaxHighUINode;

        /// <summary>
        /// 所有的面板信息
        /// </summary>
        private Dictionary<string, Panel> panels = new Dictionary<string, Panel>();

        /// <summary>
        /// 常显示界面白名单
        /// </summary>
        private List<string> whiteNames = new List<string>();

        /// <summary>
        /// 关闭时不销毁界面
        /// </summary>
        private List<string> whiteNames1 = new List<string>();

        public PanelManager()
        {
            GameObject perfab = GameObject.Find("UIRoot");
            if (perfab == null)
            {
                //创建UIRoot
                var go = Resources.Load<GameObject>("UIRoot");
                perfab = Object.Instantiate(go);
                mrgRoot = perfab.transform.GetChild(0);
            }
            else
            {
                mrgRoot = perfab.transform.GetChild(0);
            }

            //获取Canvas节点
            canvas = mrgRoot.GetComponent<Canvas>();
            canvasScaler = mrgRoot.GetComponent<CanvasScaler>();
            graphicRaycaster = mrgRoot.GetComponent<GraphicRaycaster>();

            //获取UI父节点
            uiRoot = mrgRoot.Find("UINode");

            //获取最高层级UI父节点
            MaxHighUINode = mrgRoot.Find("MaxHighUINode");

            Object.DontDestroyOnLoad(perfab);
            InitWhiteNames();
        }

        /// <summary>
        /// 初始化白名单
        /// </summary>
        void InitWhiteNames()
        {
            //whiteNames.Add(typeof(TestMainPanel).Name);
        }


        public Transform GetMaxHighUINode
        {
            get { return MaxHighUINode.transform; }
        }

        #region 加载面板并初始化UIPanelData

        //同步加载UI
        private Panel LoadPanel(string panelName)
        {
            Panel view = null;
            panels.TryGetValue(panelName, out view);
            if (view != null)
                return view;
            GameObject prefab = Engine.Res.Load<GameObject>(panelName);
            if (prefab == null)
                return null;
            GameObject panel = Object.Instantiate(prefab, Vector3.zero, Quaternion.identity, uiRoot);
            panel.name = panelName;
            view = InitPanelData(panel);
            view.gameObject.SetActive(true);
            return view;
        }

        /// <summary>
        /// 创建子面板
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <returns></returns>
        public T CreateChildPanel<T>(Transform parent) where T : ChildPanel
        {
            string name = typeof(T).Name;
            GameObject prefab = Engine.Res.Load<GameObject>(name);
            T t = Object.Instantiate(prefab, parent.position, Quaternion.identity, parent).GetComponent<T>();
            t.name = name;
            return t;
        }


        /// <summary>
        /// 初始化面板
        /// </summary>
        /// <param name="panelObj"></param>
        /// <returns></returns>
        private Panel InitPanelData(GameObject panelObj)
        {
            Panel panel = panelObj.AddMissingComponent<Panel>();
            //初始化rectTransform
            RectTransform rectTransform = panelObj.GetComponent<RectTransform>();
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.pivot = DefaultPivot;
            rectTransform.localScale = Vector3.one;
            rectTransform.anchoredPosition3D = Vector3.zero;
            rectTransform.sizeDelta = Vector2.zero;
            panels.Add(panelObj.name, panel);
            return panel;
        }

        #endregion

        #region 外部调用接口

        /// <summary>
        /// 关闭所有面板,保留主面板和公告面板
        /// </summary>
        public void CloseAllPanelButWhiteNames()
        {
            List<Panel> list = ListPool<Panel>.Get();
            list.AddRange(panels.Values);
            Panel view = null;
            for (int i = 0; i < list.Count; i++)
            {
                view = list[i];
                //不能关闭的界面
                if (whiteNames.Contains(view.gameObject.name)) continue;
                view.OnClose();
                //关闭但是不销毁的界面
                if (whiteNames1.Contains(view.gameObject.name)) continue;
                Object.Destroy(view.gameObject);
                panels.Remove(view.name);
            }

            ListPool<Panel>.Release(list);
        }

        /// <summary>
        /// 关闭所有面板
        /// </summary>
        public void CloseAllPanel()
        {
            List<string> names = new List<string>();
            names.AddRange(panels.Keys);
            string name = string.Empty;
            Panel view = null;
            for (int i = 0; i < names.Count; i++)
            {
                name = names[i];
                view = panels[name];
                panels.Remove(name);
                Object.Destroy(view.gameObject);
            }
        }

        /// <summary>
        /// 打开窗口
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T OpenPanel<T>(params object[] parameters) where T : Panel
        {
            string panelName = typeof(T).Name;
            Panel view = LoadPanel(panelName);
            view.parameters = parameters;
            view.OnOpen();
            view.transform.SetAsLastSibling();
            ResetPanelSortingOrder();
            // 播放界面开启音效
            //App.AudioMgr.PlayAudio(EnumAudio.Audio_OpenPanel);
            return view as T;
        }

        /// <summary>
        /// 打开固定层级窗口
        /// </summary>
        /// <typeparam name="T">窗口类型</typeparam>
        /// <param name="sortingOrder">渲染层级</param>
        /// <returns></returns>
        public T OpenPanel<T>(int sortingOrder) where T : Panel
        {
            string panelName = typeof(T).Name;
            Panel view = LoadPanel(panelName);
            view.OnOpen();
            view.transform.SetParent(MaxHighUINode);
            view.transform.SetAsLastSibling();
            view.SetSortingOrder(sortingOrder);
            return view as T;
        }

        /// <summary>
        /// 重置动态层级窗口的排序
        /// </summary>
        public void ResetPanelSortingOrder()
        {
            for (int i = 0; i < uiRoot.childCount; i++)
            {
                uiRoot.GetChild(i).GetComponent<Panel>().SetSortingOrder(i * ORDER_SPACE);
            }
        }

        /// <summary>
        // 关闭面板
        /// </summary>
        public void ClosePanel<T>(bool isDestroy = true)
        {
            string panelName = typeof(T).Name;
            ClosePanel(panelName, isDestroy);
        }


        /// <summary>
        // 关闭面板
        /// </summary>
        public void ClosePanel(string panelName, bool isDestroy = false)
        {
            Panel view = null;
            panels.TryGetValue(panelName, out view);
            if (view == null)
                return;
            // 播放界面开启音效
            //App.AudioMgr.PlayAudio(EnumAudio.Audio_ClosePanel);
            //关闭面板
            view.OnClose();
            if (isDestroy)
            {
                Object.Destroy(view.gameObject);
                panels.Remove(view.name);
            }
        }


        /// <summary>
        /// 获取面板
        /// </summary>
        public T GetPanel<T>() where T : Panel
        {
            string panelName = typeof(T).Name;
            if (panels.ContainsKey(panelName))
            {
                return panels[panelName] as T;
            }
            else
            {
                return null;
            }
        }

        #endregion
    }
}